-
Notifications
You must be signed in to change notification settings - Fork 46
Implement metrics for mcp tool and operation counts and durations #297
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
❌ Changeset file missing for PR All changes should include an associated changeset file. |
✅ Docs preview readyThe preview is ready to be viewed. View the preview File Changes 0 new, 6 changed, 0 removedBuild ID: 3140ca8b610261a18871af37 URL: https://www.apollographql.com/docs/deploy-preview/3140ca8b610261a18871af37 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements comprehensive OpenTelemetry metrics for the Apollo MCP Server to track operation counts and durations across GraphQL operations and MCP tool calls.
- Adds duration and count metrics for GraphQL operations with success status and operation metadata
- Implements metrics tracking for MCP tool calls including success/failure status and tool names
- Adds simple count metrics for server initialization, list tools, and get info requests
Reviewed Changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| crates/apollo-mcp-server/src/server/states/running.rs | Adds metrics collection for MCP tool calls, initialization, list tools, and get info operations |
| crates/apollo-mcp-server/src/graphql.rs | Implements metrics tracking for GraphQL operations with duration and count measurements |
| crates/apollo-mcp-server/Cargo.toml | Adds opentelemetry_sdk test dependency for metrics validation |
| .changesets/feat_otel_metrics.md | Documents the new metrics feature |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| health_check.record_rejection(); | ||
| } | ||
|
|
||
| let attributes = vec![ |
Copilot
AI
Aug 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The attributes vector is created on every tool call. Consider creating the meter and histogram instruments once during initialization and reusing them to avoid repeated allocations.
| /// Execute as a GraphQL operation using the endpoint and headers | ||
| #[tracing::instrument(skip(self))] | ||
| async fn execute(&self, request: Request<'_>) -> Result<CallToolResult, McpError> { | ||
| let meter = global::meter("apollo.mcp"); |
Copilot
AI
Aug 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The meter and histogram instruments are created on every GraphQL operation. Consider creating these once during initialization and reusing them to avoid repeated allocations and improve performance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this might warrant some merit, if we can manage it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added lazy loading into meter.rs and updated all references to call get_meter() to only initialize this once
| .u64_counter("apollo.mcp.initialize.count") | ||
| .build() | ||
| .add(1, &[]); | ||
| // TODO: how to remove these? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This leftover TODO caught my eye. 😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this was from #117
@nicholascioli Do you know what we'd need to clean this up?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks for addressing my feedback. 🙇
* Implement metrics for mcp tool and operation counts and durations * Changeset * Unit test attribute setting in graphql.rs * Add axum_otel_metrics for emitting basic http metrics about requests * Lazy load singleton Meter for metrics * Alphabetize * Simplify result.is_error checking
* Implement metrics for mcp tool and operation counts and durations * Changeset * Unit test attribute setting in graphql.rs * Add axum_otel_metrics for emitting basic http metrics about requests * Lazy load singleton Meter for metrics * Alphabetize * Simplify result.is_error checking
* Implement metrics for mcp tool and operation counts and durations * Changeset * Unit test attribute setting in graphql.rs * Add axum_otel_metrics for emitting basic http metrics about requests * Lazy load singleton Meter for metrics * Alphabetize * Simplify result.is_error checking
* Implement metrics for mcp tool and operation counts and durations * Changeset * Unit test attribute setting in graphql.rs * Add axum_otel_metrics for emitting basic http metrics about requests * Lazy load singleton Meter for metrics * Alphabetize * Simplify result.is_error checking
* Implement metrics for mcp tool and operation counts and durations * Changeset * Unit test attribute setting in graphql.rs * Add axum_otel_metrics for emitting basic http metrics about requests * Lazy load singleton Meter for metrics * Alphabetize * Simplify result.is_error checking
* Implement metrics for mcp tool and operation counts and durations * Changeset * Unit test attribute setting in graphql.rs * Add axum_otel_metrics for emitting basic http metrics about requests * Lazy load singleton Meter for metrics * Alphabetize * Simplify result.is_error checking
* Implement metrics for mcp tool and operation counts and durations * Changeset * Unit test attribute setting in graphql.rs * Add axum_otel_metrics for emitting basic http metrics about requests * Lazy load singleton Meter for metrics * Alphabetize * Simplify result.is_error checking
* Implement metrics for mcp tool and operation counts and durations * Changeset * Unit test attribute setting in graphql.rs * Add axum_otel_metrics for emitting basic http metrics about requests * Lazy load singleton Meter for metrics * Alphabetize * Simplify result.is_error checking
Apollo MCP Server Metrics
This PR adds metrics to count and measure request duration throughout the MCP server
apollo.mcpOperation-Specific Attributes
operation.id: String containing the operation identifier (persisted query ID or operation name, defaults to "unknown") - Note this is a high cardinality risk as theexecutetool can create its own operationsoperation.type: String indicating the type of operation:persisted_queryfor operations using persisted query IDsoperationfor regular GraphQL operationsTool-Specific Attributes
tool_name: String containing the name of the MCP tool being called (e.g., "introspect", "search", "explorer", "execute", "validate", or custom operation names)